package com.applcn.user.utils;

import cn.hutool.core.lang.Assert;
import com.applcn.user.config.JwtConfig;
import com.applcn.user.dto.CreateTokenDTO;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Objects;

/**
 * com.applcn.user.utils
 * Description:
 *
 * @author: 大妖怪
 * @date: 2020-01-18 14:04
 */
@Component
@RequiredArgsConstructor
public class JwtUtil {

    private final JwtConfig jwtConfig;

    private static final String USER_ID = "userId";
    private static final String MERCHANT_ID = "merchantId";

    /**
     * 生成jwt token
     * TODO 待封装, 后续增加更多信息
     *
     * @param dto
     * @return
     */
    public String createToken(CreateTokenDTO dto) {
        Assert.notNull(dto.getUserId(), "生成jwt token时用户id不能为空");
        long now = System.currentTimeMillis();
        long exp = now + jwtConfig.getExpire();
        HashMap<String, Object> claims = new HashMap<>();
        claims.put(USER_ID, dto.getUserId());
        if (dto.getMerchantId() != null) {
            claims.put(MERCHANT_ID, dto.getMerchantId());
        }

        JwtBuilder jwtBuilder = Jwts.builder()
                .setClaims(claims)
                .setSubject("user")
                .setAudience("applet")
                .setIssuer("www.applcn.com")
                .setIssuedAt(new Date())
                .setExpiration(new Date(exp))
                .signWith(SignatureAlgorithm.HS256, jwtConfig.getKey());
        return jwtBuilder.compact();
    }

    /**
     * 解析jwt token
     * TODO 针对性处理解析的几个错误
     * FIXME 待测试
     *
     * @param token
     * @return
     */
    public CreateTokenDTO resolveToken(String token) {
        Claims claims = Jwts.parser().setSigningKey(jwtConfig.getKey()).parseClaimsJws(token).getBody();
        Long merchantId = null;
        if (Objects.nonNull(claims.get(MERCHANT_ID))) {
            merchantId = Long.parseLong(claims.get(MERCHANT_ID).toString());
        }
        CreateTokenDTO dto = new CreateTokenDTO();
        dto.setUserId(Long.parseLong(claims.get(USER_ID).toString()));
        dto.setMerchantId(merchantId);
        return dto;
    }
}
